package com.manster.controller;


import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.manster.entity.SysRole;
import com.manster.entity.SysRoleMenu;
import com.manster.entity.SysUser;
import com.manster.entity.SysUserRole;
import com.manster.util.Const;
import com.manster.util.R;
import com.manster.vo.PassVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author manster
 * @since 2022-03-13
 */
@RestController
@RequestMapping("/sys/user")
@Api(tags = "用户管理")
public class SysUserController extends BaseController {

    @Autowired
    BCryptPasswordEncoder passwordEncoder;

    @ApiOperation("获取用户列表")
    @PreAuthorize("hasAuthority('sys:user:list')")
    @GetMapping("/list")
    public R list(String username){
        Page<SysUser> pageData = userService.page(getPage(),
                new QueryWrapper<SysUser>().like(StrUtil.isNotBlank(username), "username", username));

        //新增角色名
        pageData.getRecords().forEach(u -> {
            u.setSysRoles(roleService.listRolesByUserId(u.getId()));
        });

        return R.success().data(pageData);
    }

    @ApiOperation("获取用户信息")
    @PreAuthorize("hasAuthority('sys:user:list')")
    @GetMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        SysUser user = userService.getById(id);
        Assert.notNull(user,"找不到该用户");
        //获取角色列表
        List<SysRole> roles = roleService.listRolesByUserId(id);
        user.setSysRoles(roles);
        return R.success().data(user);
    }

    @ApiOperation("新增用户")
    @PreAuthorize("hasAuthority('sys:user:save')")
    @PostMapping("/save")
    public R save(@Validated @RequestBody SysUser sysUser){
        //设置默认密码
        String password = passwordEncoder.encode(Const.DEFAULT_PASSWORD);
        sysUser.setPassword(password);

        //设置默认头像
        sysUser.setAvatar(Const.DEFAULT_AVATAR);
        userService.save(sysUser);

        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(sysUser.getId());
        //默认设为普通用户
        userRole.setRoleId(3L);
        userRoleService.save(userRole);
        return R.success().data(sysUser);
    }

    @ApiOperation("修改用户信息")
    @PreAuthorize("hasAuthority('sys:user:update')")
    @PostMapping("/update")
    public R update(@Validated @RequestBody SysUser sysUser){
        userService.updateById(sysUser);
        return R.success().data(sysUser);
    }

    @ApiOperation("删除用户信息")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    @PostMapping("/delete/{id}")
    @Transactional
    public R delete(@PathVariable("id") Long id){
        userService.removeById(id);
        //删除中间表
        userRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id",id));
        return R.success();
    }

    @ApiOperation("批量删除用户信息")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    @PostMapping("/deleteBatch")
    @Transactional
    public R deleteBatch(@RequestBody Long[] ids){
        userService.removeByIds(Arrays.asList(ids));
        //删除中间表
        userRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id",ids));
        return R.success();
    }

    @ApiOperation("为用户分配角色")
    @PreAuthorize("hasAuthority('sys:user:role')")
    @PostMapping("/perm/{userId}")
    @Transactional
    public R rolePerm(@PathVariable("userId") Long userId, @RequestBody Long[] roleIds){

        List<SysUserRole> userRoles = new ArrayList<>();

        Arrays.stream(roleIds).forEach(r -> {
            SysUserRole userRole = new SysUserRole();
            userRole.setRoleId(r);
            userRole.setUserId(userId);
            userRoles.add(userRole);
        });

        //先删除原来的所有菜单记录，然后保存新的记录
        userRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id",userId));
        userRoleService.saveBatch(userRoles);

        //删除缓存
        SysUser user = userService.getById(userId);
        userService.clearUserAuthorityInfo(user.getUsername());

        return R.success();
    }

    @ApiOperation("重置密码")
    @PreAuthorize("hasAuthority('sys:user:repass')")
    @PostMapping("/repass")
    public R repass(@RequestBody Long id){
        SysUser user = userService.getById(id);
        user.setPassword(passwordEncoder.encode(Const.DEFAULT_PASSWORD));
        userService.updateById(user);
        return R.success();
    }

    @ApiOperation("修改密码")
    @PostMapping("/updatePass")
    public R updatePass(@Validated @RequestBody PassVo passVo, Principal principal){
        SysUser user = userService.getByUsername(principal.getName());

        boolean matches = passwordEncoder.matches(passwordEncoder.encode(passVo.getCurrentPass()), user.getPassword());

        if(matches){
            return R.fail().msg("旧密码不正确");
        }

        user.setPassword(passwordEncoder.encode(passVo.getPassword()));
        userService.updateById(user);
        return R.success().msg("修改密码成功");
    }

}
